package com.wulis.provider.basic.service.impl;

import static com.wulis.common.model.enums.HttpStatusEnum.ILLEGAL_ARGUMENT;

import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wulis.common.exception.BusinessException;
import com.wulis.common.model.enums.DeletedStateEnum;
import com.wulis.common.support.BaseServiceImpl;
import com.wulis.common.utils.NodeUtil;
import com.wulis.provider.basic.mapper.DepartmentMapper;
import com.wulis.provider.basic.model.dto.InsertDepartmentDto;
import com.wulis.provider.basic.model.dto.QueryDepartmentTreeDto;
import com.wulis.provider.basic.model.dto.UpdateDepartmentDto;
import com.wulis.provider.basic.model.entity.Department;
import com.wulis.provider.basic.model.vo.InsertDepartmentVo;
import com.wulis.provider.basic.model.vo.QueryDepartmentTreeVo;
import com.wulis.provider.basic.model.vo.QueryDepartmentVo;
import com.wulis.provider.basic.service.DepartmentService;

import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

/**
 * 基础信息管理：部门信息表 Service实现类
 *
 * @author WuliBao
 * @date 2020-05-21
 */
@Slf4j
@Service
@AllArgsConstructor
public class DepartmentServiceImpl extends BaseServiceImpl<DepartmentMapper, Department> implements DepartmentService {
    
    private final DepartmentMapper departmentMapper;
    
    /**
     * WEB:查询部门信息列表(树形)
     *
     * @param queryDepartmentTreeDto queryDepartmentTreeDto
     * @return List
     */
    @Override
    public List<QueryDepartmentTreeVo> queryDepartmentTree(@NonNull QueryDepartmentTreeDto queryDepartmentTreeDto) {
        // 查询部门信息列表
        List<QueryDepartmentTreeVo> departmentList =
            departmentMapper.queryDepartmentList(queryDepartmentTreeDto.getOrganizationId(),
                queryDepartmentTreeDto.getDepartmentName(),
                queryDepartmentTreeDto.getEnable());
        // 列表转树形结构
        return NodeUtil.buildTree(departmentList);
    }
    
    /**
     * WEB:查询部门信息
     *
     * @param id id
     * @return QueryDepartmentVo
     */
    @Override
    public QueryDepartmentVo queryDepartment(@NonNull Long id) {
        return departmentMapper.queryDepartment(id);
    }
    
    /**
     * WEB:新增部门信息
     *
     * @param insertDepartmentDto insertDepartmentDto
     * @return Integer
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public InsertDepartmentVo insertDepartment(@NonNull InsertDepartmentDto insertDepartmentDto) {
        // 默认的父级IDS
        String parentIds = "/";
        Department department = new Department();
        BeanUtils.copyProperties(insertDepartmentDto, department);
        // 判断是否为根节点
        if (insertDepartmentDto.getParentId() == null || insertDepartmentDto.getParentId() == 0L) {
            insertDepartmentDto.setParentId(0L);
            parentIds = parentIds + 0L + parentIds;
        }
        else {
            // 查询父级部门
            Department parentDepartment = departmentMapper.selectById(insertDepartmentDto.getParentId());
            if (parentDepartment == null) {
                throw new BusinessException(ILLEGAL_ARGUMENT);
            }
            else {
                parentIds = parentDepartment.getParentIds() + parentDepartment.getId() + parentIds;
                department.setOrganizationId(parentDepartment.getOrganizationId());
            }
        }
        department.setParentIds(parentIds);
        // 新增部门
        departmentMapper.insert(department);
        // 返回插入的部门
        InsertDepartmentVo insertDepartmentVo = new InsertDepartmentVo();
        BeanUtils.copyProperties(department, insertDepartmentVo);
        return insertDepartmentVo;
    }
    
    /**
     * WEB:修改部门信息
     *
     * @param updateDepartmentDto updateDepartmentDto
     * @return Integer
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateDepartment(@NonNull UpdateDepartmentDto updateDepartmentDto) {
        // 默认的父级IDS
        String parentIds = "/";
        Department department = new Department();
        BeanUtils.copyProperties(updateDepartmentDto, department);
        // 判断是否为根节点
        if (updateDepartmentDto.getParentId() == null || updateDepartmentDto.getParentId() == 0L) {
            department.setParentId(0L);
            parentIds = parentIds + 0L + parentIds;
        }
        else {
            // 查询父级部门
            Department parentDepartment = departmentMapper.selectById(updateDepartmentDto.getParentId());
            if (parentDepartment != null) {
                parentIds = parentDepartment.getParentIds() + parentDepartment.getId() + parentIds;
                department.setOrganizationId(parentDepartment.getOrganizationId());
            }
            else {
                throw new BusinessException(ILLEGAL_ARGUMENT);
            }
        }
        // 查询未修改前的parentIds
        Department oldDepartment = departmentMapper.selectById(updateDepartmentDto.getId());
        String oldParentIds = oldDepartment.getParentIds() + oldDepartment.getId() + "/";
        // 修改部门
        department.setParentIds(parentIds);
        int update = departmentMapper.updateById(department);
        // 修改后的parentIds
        String newParentIds = department.getParentIds() + department.getId() + "/";
        // 修改下级部门关联的机构ID及parentIds
        departmentMapper.updateChildDepartment(department.getOrganizationId(), oldParentIds, newParentIds);
        return update;
    }
    
    /**
     * WEB:删除部门信息
     *
     * @param id id
     * @return Integer
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteDepartment(@NonNull Long id) {
        // 获取当前用户信息
        // 删除部门及下级部门(逻辑删除)
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Department::getId, id).or().like(Department::getParentIds, "/" + id + "/");
        Department department = new Department();
        department.setDeleted(DeletedStateEnum.IS_DELETED.value());
        return departmentMapper.update(department, queryWrapper);
    }
    
    /**
     * WEB:删除部门信息(根据组织机构ID)
     *
     * @param organizationId organizationId
     * @return Integer
     */
    @Override
    public Integer deleteDepartmentByOrganizationId(@NonNull Long organizationId) {
        // 根据组织结构ID删除部门信息
        Department department = new Department();
        department.setDeleted(DeletedStateEnum.IS_DELETED.value());
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Department::getOrganizationId, organizationId);
        return departmentMapper.update(department, queryWrapper);
    }
}
